package com.cnbm.wcsbasic.protocol.netty.io.common;



import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
import com.cnbm.wcsbasic.protocol.netty.io.common.byteutils.ByteUtils;

import java.util.Arrays;
import java.util.Collection;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

public class CaffeineUtil {

    /**
     * 缓存的最大容量
     */
    private static final int MAXIMUM_SIZE = 1000;

    /**
     * 缓存项的写入后过期时间
     */
    private static final int EXPIRE_AFTER_WRITE_DURATION = 10;

    /**
     * 过期时间单位（分钟）
     */
    private static final TimeUnit EXPIRE_AFTER_WRITE_TIMEUNIT = TimeUnit.MINUTES;

    private static Cache<String, Object> cache;
    private static Cache<String, AtomicInteger> cacheUUID;

    /**
     * 初始化Caffeine缓存配置
     */
    static {
        //todo  https://github.com/ben-manes/caffeine/wiki 研究一下，然后升级一下版本
        cache = Caffeine.newBuilder()
                .maximumSize(MAXIMUM_SIZE)
                .expireAfterWrite(EXPIRE_AFTER_WRITE_DURATION, EXPIRE_AFTER_WRITE_TIMEUNIT)
                .build();

        cacheUUID = Caffeine.newBuilder()
                .maximumSize(10)
                .expireAfterWrite(Long.MAX_VALUE, EXPIRE_AFTER_WRITE_TIMEUNIT)
                .build();
    }

    public static void main(String[] args) {
        byte[] a = getUUID();
        byte[] b = getUUID();
        byte[] d = ByteUtils.intToBytes(300);
        byte[] c = ByteUtils.intToBytes(32000);
        //todo int 转两个字节长度
        System.out.println(Arrays.asList(getUUID()));

    }



    public static synchronized byte[] getUUID() {
        AtomicInteger uuid = cacheUUID.getIfPresent("UUID");
        if(uuid == null){
            //transationId 从1 开始，0留给心跳变量，这样就固定报文了
            cacheUUID.put("UUID",new AtomicInteger(1));
            return ByteUtils.intToBytes(1);
        }else {
            if(uuid.get() >= 32000){
                cacheUUID.put("UUID",new AtomicInteger(1));
                return ByteUtils.intToBytes(1);
            }else {
                return ByteUtils.intToBytes(uuid.incrementAndGet());
            }
        }
    }

    public static synchronized byte[] getUUIDAGV() {
        AtomicInteger agvuuid = cacheUUID.getIfPresent("AGVUUID");
        if(agvuuid == null){
            //transationId 从1 开始，0留给心跳变量，这样就固定报文了
            cacheUUID.put("AGVUUID",new AtomicInteger(1));
            return ByteUtils.intToBytesS(1);
        }else {
            if(agvuuid.get() >= 32000){
                cacheUUID.put("AGVUUID",new AtomicInteger(1));
                return ByteUtils.intToBytesS(1);
            }else {
                return ByteUtils.intToBytesS(agvuuid.incrementAndGet());
            }
        }
    }

    /**
     * 获取缓存值
     *
     * @param key 缓存键
     * @return 缓存值
     */
    public static Object get(String key) {
        return cache.getIfPresent(key);
    }

    /**
     * 设置缓存值
     *
     * @param key   缓存键
     * @param value 缓存值
     */
    public static void put(String key, Object value) {
        cache.put(key, value);
    }

    /**
     * 移除缓存项
     *
     * @param key 缓存键
     */
    public static void remove(String key) {
        cache.invalidate(key);
    }

    /**
     * 清空缓存
     */
    public static void clear() {
        cache.invalidateAll();
    }

    /**
     * 获取缓存中的所有值
     *
     * @return 缓存中的所有值集合
     */
    public static Collection<Object> getAllValues() {
        return cache.asMap().values();
    }

    /**
     * 清空缓存中的所有值
     */
    public static void removeAllValues() {
        cache.invalidateAll();
    }
}
